package br.ufpe.cin.rdfilter.feedback;

import java.util.List;
import java.util.Vector;

/**
 * 
 * @author helio
 *
 * This class we calculate precision, recall and F-measure over a feedback
 */

public class Feedback {
	double alfa;
	double precision;
	double recall;
	double f_measure;
	int tp = 0;
	int fp = 0;
	int fn = 0;
	private String query;
	private List<Annotation> annotation;

	public Feedback(String query, List<Annotation> annotation) {
		this.query = query;
		this.annotation = annotation;
		calculate(annotation);
	}

	/**
	 * 
	 * @param annotation
	 * If an annotation is true positive, then tp++
	 * If an annotation is false positive, then fp++
	 * If an annotation is false negative, then fn++
	 * Precision = tp /(tp+fp)
	 * Recall = tp/(tp+fn)
	 * F = 2*P*R/(P+R)
	 */
	private void calculate(List<Annotation> annotation) {
		for (int i = 0; i < annotation.size(); i++) {
			if (annotation.get(i).getType().equals("True Positive")) {
				tp++;
			} else if (annotation.get(i).getType().equals("False Positive")) {
				fp++;
			} else if (annotation.get(i).getType().equals("False Negative")) {
				fn++;
			}
		}
		if(tp==0 && fp ==0)
			precision=0.0;
		else precision = ((double) (tp)) / ((double) (tp + fp));
		if(tp==0 && fn==0)
			recall=0.0;
		else recall = ((double) (tp)) / ((double) (tp + fn));
		
		if(precision==0.0 || recall==0.0)
			f_measure=0.0;
		else f_measure = 2 * precision * recall / (precision + recall);
	}
	
	/**
	 * If P,R and F are updated, recalculate with new values of tp,fp and fn 
	 */
	public void recalculate(){
		if(tp==0 && fp ==0)
			precision=0.0;
		else precision = ((double) (tp)) / ((double) (tp + fp));
		if(tp==0 && fn==0)
			recall=0.0;
		else recall = ((double) (tp)) / ((double) (tp + fn));
		
		if(precision==0.0 || recall==0.0)
			f_measure=0.0;
		else f_measure = 2 * precision * recall / (precision + recall);
	}
	
	public List<Annotation> getAnnotation() {
		return this.annotation;
	}

	public void setAnnotation(List<Annotation> annotation) {
		this.annotation = annotation;
	}

	public double getPrecision() {
		return precision;
	}

	public void setPrecision(int tp, int fp) {
		precision = tp / (tp + fp);
	}

	public double getRecall() {
		return recall;
	}

	public void setRecall(int tp, int fn) {
		recall = tp / (tp + fn);
	}

	public double getF_measure() {
		return f_measure;
	}

	public void setF_measure(double precision, double recall, double alfa) {
		this.f_measure = 1 / (alfa / precision + (1 - alfa) / recall);
	}

	public double getAlfa() {
		return alfa;
	}

	public void setAlfa(double alfa) {
		this.alfa = alfa;
	}

	public String getQuery() {
		return query;
	}

	public void setQuery(String query) {
		this.query = query;
	}

	public int getTp() {
		return tp;
	}

	public void setTp(int tp) {
		this.tp = tp;
	}

	public int getFp() {
		return fp;
	}

	public void setFp(int fp) {
		this.fp = fp;
	}

	public int getFn() {
		return fn;
	}

	public void setFn(int fn) {
		this.fn = fn;
	}
}